package com.study.springsecurity.service.security;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.study.springsecurity.constant.CommonConstant;
import com.study.springsecurity.mapper.UserInfoMapper;
import com.study.springsecurity.pojo.MyUserDetails;
import com.study.springsecurity.pojo.entity.MenuEntity;
import com.study.springsecurity.pojo.entity.RoleEntity;
import com.study.springsecurity.pojo.entity.UserEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class DBUserDetailsService implements UserDetailsService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper();
        wrapper.eq("username", username);
        UserEntity userEntity = userInfoMapper.selectOne(wrapper);
        if (userEntity == null) {
            throw new UsernameNotFoundException("用户名不存在！");
        }

        // 获取用户角色、菜单列表
        List<RoleEntity> roleList = userInfoMapper.selectRoleByUserId(userEntity.getId());
        List<MenuEntity> menuList = userInfoMapper.selectMenuByUserId(userEntity.getId());

        log.info("selectOne username={},userInfo={},roles={},menus={}", username, userEntity, roleList, menuList);

        List<GrantedAuthority> grantedAuthorityList = new ArrayList<>(); // 声明一个集合List<GrantedAuthority>
        // List<GrantedAuthority> grantedAuthorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("role1,role2");
        // List<GrantedAuthority> grantedAuthorityList = AuthorityUtils.createAuthorityList(menus.toArray(new String[0]));

        // 处理角色
        for (RoleEntity roleEntity : roleList) {
            // 角色之所以要使用ROLE_开头，是为了和ExpressionUrlAuthorizationConfigurer.AuthorizedUrl.hasRole(String role)方法一致
            grantedAuthorityList.add(new SimpleGrantedAuthority(CommonConstant.Role.ROLE_PREFIX + roleEntity.getName()));
        }

        // 处理权限
        for (MenuEntity menuEntity : menuList) {
            // 和ExpressionUrlAuthorizationConfigurer.AuthorizedUrl.hasAuthority(String authority)相对应
            grantedAuthorityList.add(new SimpleGrantedAuthority(menuEntity.getPermission()));
        }
        return new MyUserDetails(userEntity.getId(), userEntity.getUsername(), userEntity.getPassword(), grantedAuthorityList);
    }
}
